<script setup>
import { fabric } from 'fabric'

import { useAttrs } from '@/hooks/useAttrs'
import { useInitCanvas } from '@/hooks/useInitCanvas'
import { useShapeOpt } from '@/hooks/useShapeOpt'
import { useSelectImg } from '@/hooks/useSelectImg'
import { useSaveImg } from '@/hooks/useSaveImg'

import {
  Plus,
  ZoomIn,
  Delete,
  Edit,
  EditPen,
  Search,
  FullScreen,
  CaretTop,
  TopRight,
} from '@element-plus/icons-vue'

// 左侧图片
const fileList = ref([])

// 预览
const dialogImageUrl = ref('')
const dialogVisible = ref(false)

// canvasRef
const canvasRef = ref(null)

// 当前选中的图片
const currentTplId = ref('')

// 边框填充属性相关
const { attrs, updateAttr, predefineColors } = useAttrs(canvasRef)

// 初始化画布属性相关
const { initCanvas } = useInitCanvas(canvasRef, attrs)

// 图形插入画布操作
const { insertShape } = useShapeOpt(canvasRef)

// 左边图片选择
const { initSelectImg, handleSelect, handleRemove, handlePictureCardPreview } = useSelectImg({
  canvasRef,
  fileList,
  currentTplId,
  dialogImageUrl,
  dialogVisible,
})

// 右边按钮操作
const { handlePreview, handleDownload, handleSaveTpl, handleClear, handleCreate } = useSaveImg({
  canvasRef,
  fileList,
  currentTplId,
  dialogImageUrl,
  dialogVisible,
})

// 初始化
const init = () => {
  // ⚠️标记画布为原生对象
  canvasRef.value = markRaw(new fabric.Canvas('c'))
  initCanvas()
  initSelectImg()
}

onMounted(init)
</script>

<template>
  <div class="flex flex-justify-center p-20px">
    <section class="w-340px p-10px">
      <h3 class="text-center">图片编辑</h3>
      <el-upload
        v-model:file-list="fileList"
        list-type="picture-card"
        :auto-upload="false"
        :limit="9"
      >
        <el-icon><Plus /></el-icon>
        <template #file="{ file }">
          <div>
            <img class="el-upload-list__item-thumbnail" :src="file.url" />
            <span class="el-upload-list__item-actions">
              <span @click="handlePictureCardPreview(file)">
                <el-icon><ZoomIn /></el-icon>
              </span>
              <span @click="handleSelect(file)">
                <el-icon><Edit /></el-icon>
              </span>
              <span @click="handleRemove(file)">
                <el-icon><Delete /></el-icon>
              </span>
            </span>
          </div>
        </template>
        <template #tip>
          <div class="el-upload__tip">
            选择图片
          </div>
        </template>
      </el-upload>
    </section>

    <section class="ml-10px mr-10px editor">
      <canvas id="c" width="500" height="500"></canvas>
    </section>

    <section class="w-240px p-10px">
      <div>
        <h3 class="text-center">属性编辑</h3>
        <div>
          <div class="p-12px">
            <span>填充：</span>
            <el-color-picker
              v-model="attrs.fill"
              show-alpha
              :predefine="predefineColors"
              @change="val => updateAttr('fill', val)"
            />
          </div>
          <div class="p-12px">
            <span>边框：</span>
            <el-color-picker
              v-model="attrs.stroke"
              show-alpha
              :predefine="predefineColors"
              @change="val => updateAttr('stroke', val)"
            />
          </div>
          <div class="p-12px">
            <span>边框宽度：</span>
            <el-input-number
              v-model="attrs.strokeWidth"
              :min="0"
              :max="20"
              size="small"
              controls-position="right"
              class="w-100px"
              @change="val => updateAttr('strokeWidth', val)"
            />
          </div>
        </div>
      </div>
      <div>
        <h3 class="text-center">插入元素</h3>
        <div class="flex flex-wrap">
          <el-icon size="50" class="m-10px" @click="insertShape('IText')"><EditPen /></el-icon>
          <el-icon size="50" class="m-10px" @click="insertShape('Rect')"><FullScreen /></el-icon>
          <el-icon size="50" class="m-10px" @click="insertShape('Circle')"><Search /></el-icon>
          <el-icon size="50" class="m-10px" @click="insertShape('Triangle')"><CaretTop /></el-icon>
          <el-icon size="50" class="m-10px" @click="insertShape('Arrow')"><TopRight /></el-icon>
        </div>
      </div>
      <div>
        <h3 class="text-center">画布编辑</h3>
        <el-button @click="handleCreate" type="primary" plain>新建画布</el-button>
        <el-button @click="handlePreview" plain>预览</el-button>
        <el-button @click="handleSaveTpl" type="primary">保存画布</el-button>
        <el-button @click="handleDownload" type="success">下载画布</el-button>
        <el-button @click="handleClear" type="warning">清除画布</el-button>
      </div>
    </section>
  </div>

  <el-dialog v-model="dialogVisible" align-center width="auto">
    <img :src="dialogImageUrl" class="w-200" />
  </el-dialog>
</template>

<style scoped>
.editor {
  height: fit-content;
  border: 1px solid #ccc;
  position: relative;
  box-shadow: 0 0 4px rgba(0, 0, 0, 0.1);
  background-image: radial-gradient(rgba(9, 89, 194, 0.3) 6%, transparent 0),
    radial-gradient(#faf9f8 6%, transparent 0);
  background-size: 10px 10px;
  background-position: 0 0, 2px 2px;
}
</style>
